package com.xm.bluetoothkotlin.util

import android.util.Log
import com.blankj.utilcode.util.LogUtils
import java.lang.Exception
import java.util.*
import kotlin.experimental.and

/**
 * @创建者:小垚
 * @时间:2021/11/18
 *@描述:
 */
object ByteUtil {
    private val HEX_CHAR = mutableListOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')

    /**
     *字节数组转16进制字符
     */
    fun bytesToHex(bytes: ByteArray): String {
        // 一个byte为8位，可用两个十六进制位标识
        val buf = CharArray(bytes.size * 2)
        var a = 0
        var index = 0
        for (b in bytes) { // 使用除与取余进行转换
            a = if (b < 0) {
                256 + b
            } else {
                b.toInt()
            }
            buf[index++] = HEX_CHAR[a / 16]
            buf[index++] = HEX_CHAR[a % 16]
        }
        return String(buf).uppercase()
    }

    fun string2Unicode(word: String): String? {
        val unicode = StringBuffer()
        for (element in word) {
            // 转换为unicode, 实测不需要\\u
            unicode.append("\\u" + Integer.toHexString(element.code))
        }
        return unicode.toString()
    }

    /**
     * char转为16bit unicode
     * 高位在前, 低位在后
     *
     * @param word
     * @return
     */
    fun chatTo16bitUnicodeWithBytes(word: Char): ByteArray {
        var data = hexStringToByteArray(Integer.toHexString(word.code))
        for (i in data.indices) {
            LogUtils.e("ByteUtil", "unicode:" + Integer.toHexString(data[i].toInt()))
        }
        if (data.size == 1) {
            data = byteArrayOf(0x00, data[0])
        }
        return data
    }

    /**
     * 16进制转字节数组
     *
     * @param s
     * @return
     */
    fun hexStringToByteArray(s: String): ByteArray {
        val len = s.length
        val data = ByteArray(len / 2)
        var i = 0
        while (i < len) {
            data[i / 2] = ((Character.digit(s[i], 16) shl 4) + Character.digit(s[i + 1], 16)).toByte()
            i += 2
        }
        return data
    }

    fun sumCheck(data: ByteArray): ByteArray {
        var sum = 0
        for (i in data.indices) {
            sum += data[i]
        }
        if (sum > 0xff) { //超过了255，使用补码（补码 = 原码取反 + 1）
            sum = sum.inv()
            sum += 1
        }
        return byteArrayOf((sum and 0xff).toByte())
    }

    /**
     * 字节数组转16进制字符串 中间中 空格符 分割
     *
     * @param bytes
     * @return
     */
    fun bytesToHexSegment(bytes: ByteArray): String {
        // 一个byte为8位，可用两个十六进制位标识
        val buf = CharArray(bytes.size * 2)
        var a = 0
        var index = 0
        val stringBuffer = StringBuffer()
        try {
            for (b in bytes) { // 使用除与取余进行转换
                a = if (b < 0) {
                    256 + b
                } else {
                    b.toInt()
                }
                buf[index++] = HEX_CHAR[a / 16]
                stringBuffer.append(buf[index - 1].uppercaseChar())
                buf[index++] = HEX_CHAR[a % 16]
                stringBuffer.append(buf[index - 1].uppercaseChar())
                stringBuffer.append(" ")
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return stringBuffer.toString()
    }

    /**
     * 字节数组转化成集合
     */
    fun bytesToArrayList(bytes: ByteArray): MutableList<Int> {
        val datas = mutableListOf<Int>()
        bytes.forEachIndexed { _, byte ->
            datas.add((byte and 0xFF.toByte()).toInt())
        }
        return datas
    }


    fun bytes2Int(bytes: ByteArray): Int {
        //如果不与0xff进行按位与操作，转换结果将出错，有兴趣的同学可以试一下。
        val int1: Int = (bytes[3] and 0xFF.toByte()).toInt()
        val int2: Int = (bytes[2] and 0xFF.toByte()).toInt() shl 8
        val int3: Int = (bytes[1] and 0xFF.toByte()).toInt() shl 16
        val int4: Int = (bytes[0] and 0xFF.toByte()).toInt() shl 24
        return int1 + int2 + int3 + int4
    }

    fun bytes2Short(bytes: ByteArray): Int {
        val int1: Int = (bytes[1] and 0xFF.toByte()).toInt()
        val int2: Int = (bytes[0] and 0xFF.toByte()).toInt() shl 8
        return int1 + int2
    }

    /**
     * 十六进制String转换成Byte[] * @param hexString the hex string * @return byte[]
     */
    fun hexStringToBytes(hexString: String): ByteArray {
        var hexString = hexString
        if (hexString == null || hexString == "") {
            return byteArrayOf()
        }
        hexString = hexString.uppercase(Locale.getDefault())
        if (hexString.length % 2 != 0) {
            hexString = "0$hexString"
        }
        val length = hexString.length / 2
        val hexChars = hexString.toCharArray()
        val d = ByteArray(length)
        for (i in 0 until length) {
            val pos = i * 2
            d[i] = ((charToByte(hexChars[pos])).toInt() shl 4 or charToByte(hexChars[pos + 1]).toInt()).toByte()
        }
        return d
    }

    /**
     * Convert char to byte * @param c char * @return byte
     */
    private fun charToByte(c: Char): Byte {
        return "0123456789ABCDEF".indexOf(c).toByte()
    }

    fun fromShort(n: Short): ByteArray {
        return byteArrayOf(
            n.toByte(), (n.toInt() ushr 8).toByte()
        )
    }

}